package com.eastcom.groovy.distributor


import org.apache.log4j.Logger;
import java.util.ArrayList;




import com.eastcom.groovy.tools.db.DbEngine
import java.sql.Date;
import java.sql.Timestamp
import java.sql.Types;
import java.text.SimpleDateFormat
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.ArrayList;

import com.eastcom.groovy.provider.*



/**
 * Processor的接收线程。 负责接收客户端发来的数据并转送到处理线程中。
 *
 * @author 张海峰
 * @version 1.0
 */
public class WorkerThread extends Thread {
	//~ Static fields/initializers ---------------------------------------------

	private static Logger logger = Logger.getLogger(WorkerThread.class);

	private static Map<String, Integer[]> sqlTypeList = new HashMap<String, Integer[]>()
	private static List<String> timeFormatList = new ArrayList<String>()
	//~ Instance fields --------------------------------------------------------
	//private int serNum;
	private Socket       socket = null;

	//~ Constructors -----------------------------------------------------------

	/**
	 * Creates a new WorkerThread object.
	 *
	 * @param socket DOCUMENT ME!
	 * @param cfi DOCUMENT ME!
	 * @param tt DOCUMENT ME!
	 */
	public WorkerThread(Socket socket) {
		this.socket = socket;
		//serNum=createSerNum();
		//logger.info("Socket thread-"+this.serNum+" was established.");
		this.start();
	}

	//~ Methods ----------------------------------------------------------------

	/**
	 * DOCUMENT ME!
	 */
	public void run() {
		String timeFmt = PropertyPlaceholderConfigurerProvider.getContextProperty("TimeFormate")
		if(timeFmt == null){
			timeFmt = "yyyy-MM-dd HH:mm:ss,yyyy/MM/dd HH:mm:ss,yyyy-MM-dd,yyyy/MM/dd"
		}
		String[] timeFormate = timeFmt.split("\\s*,\\s*")
		timeFormate.each {
			timeFormatList.add(it)
		}
		InputStream inp=null
		try {
			//InputStream in = new BufferedInputStream(socket.getInputStream());
			inp = new BufferedInputStream(socket.getInputStream());
			//byte[] ba = new
			// byte[SimpleKit.toInt(cfi.getValue("MaxLineSize"))];
			byte[] baLen  = new byte[QueueConst.LENGTH_FLAG_LENGTH];
			byte[] ba;
			int    sepLen = QueueConst.WORD_SEPARATOR.length();

			while (true) {
				try {
					int count0 = inp.read(baLen);

					if (count0 == -1) {
						break;
					}

					while (count0 < QueueConst.LENGTH_FLAG_LENGTH) {
						count0 += inp.read(baLen, count0,
								QueueConst.LENGTH_FLAG_LENGTH -
								count0);
					}

					int i = Integer.valueOf(new String(baLen)) -
							QueueConst.LENGTH_FLAG_OFFSET;

					if (i < 0) {
						logger.error("Invalid number，<0:" + i);

						break;
					}

					try {
						ba = new byte[i];
					} catch (OutOfMemoryError oom) {
						//                        tt.clearBank();
						ba = new byte[i];
						logger.error("Memory exhausted, clear buffer. ");
					}

					int counts = inp.read(ba);

					while (counts < i) {
						counts += inp.read(ba, counts, i - counts);
					}
					if(parseLine(new String(ba))==null){
						continue
					}
					logger.info("" + ++counts);
					//                    tt.transmit(new String(ba,
					//                                           sepLen +
					//                                           QueueConst.MODULE_CODE_PREFIX_LENGTH,
					//                                           QueueConst.MODULE_CODE_LENGTH),
					//                                new String(ba, sepLen, ba.length - sepLen));
				} catch (OutOfMemoryError oom) {
					logger.error("Memory exhausted, clear buffer.");
				}
			}
		} catch (Exception e) {
			//e.printStackTrace();
			logger.error(e);
		}finally{
			if(inp!=null)
			{
				try{
					inp.close();
				}catch(IOException ioe)
				{}
				inp=null;
			}
			if(this.socket!=null)
			{
				try{
					this.socket.close();
				}catch(IOException ioe)
				{
					logger.error(ioe);
				}
				this.socket=null;
			}
			//logger.info("Socket thread-"+this.serNum+" was closed.");
		}
	}

	private boolean parseLine(String line){
		try {
			List<String> valueList = new ArrayList<String>()
			String[] values = line.split("\\|\\|")
			if(values == null || values.length <= 3){
				return
			}
			for(int i = 3; i < values.length; i++){
				valueList.add(values[i])
			}
			StringBuffer sqlBf = new StringBuffer()
			sqlBf.append("insert into ")
			println values[1]+"----"+values[2]
			String table = DPService.table.get(values[1])
			Map<String,String> feildList = DPService.feild.get(values[1])
			println table
			if(table == null){
				return false
			}
			sqlBf.append(table+"(")
			for(int i = 0; i < values[2].trim().length(); i++){
				char c = values[2].charAt(i)
				println c
				String seq = c.toString()
				sqlBf.append(feildList.get(seq))
				if(i < values[2].trim().length()-1){
					sqlBf.append(",")
				}
			}
			sqlBf.append(") values(")
			for(int i = 0; i < values[2].trim().length(); i++){
				sqlBf.append("?")
				if(i < values[2].trim().length()-1){
					sqlBf.append(",")
				}
			}
			sqlBf.append(")")
			println sqlBf.toString()
			doInsertResult(valueList,sqlBf.toString(),values[1])
		} catch (Exception e) {
			e.printStackTrace()
		}

	}

	private boolean doInsertResult(List<String> raw, String sql, String tbId){
		DbEngine dbEngine = SpringContextProvider.getBean("dbEngine")
		List<String> dbList = DPService.actionRuleList.get(tbId)
		List<String> dstFieldList = new ArrayList()
		List<Integer> dstFieldTypeList = new ArrayList()
		dbList.each {
			dbEngine.getJdbcUtil().setDataSource(SpringContextProvider.getBean(it))
			int[] sqlTypes = sqlTypeList.get(tbId)
			if(sqlTypes == null || sqlTypes.length == 0){
				sql = DbEngine.doDbInit(it, dstFieldList, dstFieldTypeList, sql, false)
				sqlTypes = new int[dstFieldTypeList.size()]
				for(int i = 0; i < dstFieldTypeList.size(); i++){
					sqlTypes[i] = dstFieldTypeList.get(i)
				}
				sqlTypeList.put(tbId, sqlTypes)
			}
			Object[] param = new Object[raw.size()]
			for(int i = 0; i < raw.size(); i++){
				String value = raw.get(i)
				try {
					switch(sqlTypes[i]){
						case Types.INTEGER:
							param[i] = Integer.valueOf(value)
							break
						case Types.FLOAT:
						case Types.DOUBLE:
							param[i] = Double.valueOf(value)
							break
						case Types.DECIMAL:
						case Types.NUMERIC:
							param[i] = BigDecimal.valueOf(Double.valueOf(value))
							break
						case Types.TIMESTAMP:
							java.util.Date date = null;
							Timestamp time
							boolean isFd = false
							for(int j = 0; j < timeFormatList.size(); j++) {
								try {
									SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormatList.get(j));
									date = simpleDateFormat.parse(value)
									println(date)
									isFd = true
									break;
								} catch (Exception e) {
									// TODO: handle exception
									println("时间转换错误！时间："+value+"格式："+timeFormatList.get(j))
									continue
								}
							}
							logger.debug(date.toLocaleString());
							SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
							String string = simpleDateFormat2.format(date);
							logger.debug(string);
							Timestamp timestamp = Timestamp.valueOf(string);
							param[i] = timestamp
							break
						case Types.DATE:
							java.util.Date date = null;
							boolean isFd = false
							for(int j = 0; j < timeFormatList.size(); j++) {
								try {
									SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormatList.get(j));
									date = simpleDateFormat.parse(value)
									println(date)
									isFd = true
									break;
								} catch (Exception e) {
									// TODO: handle exception
									println("时间转换错误！时间："+value+"格式："+timeFormatList.get(j))
									continue
								}
							}
							logger.debug(date.toLocaleString());
							SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
							String string = simpleDateFormat2.format(date);
							logger.debug(string);
							param[i] = new java.sql.Date(date.getTime())
							break
						case Types.VARCHAR:
						case Types.NVARCHAR:
							param[i] = value
							break
						case Types.OTHER:
							param[i] = value
							break;
						default:
							param[i] = null
							logger.warn("入库数据库字段无法识别！使用Null插入！")
							break;
					}
				} catch (Exception e) {
					e.printStackTrace()
					logger.error(e.getMessage())
					param[i]=null
				}
			}
			try{
				dbEngine.getJdbcUtil().update(sql, param, sqlTypes)
			}catch(Exception e){
				e.printStackTrace()
				logger.error(e.getMessage())
			}
			println ""
		}
	}
}